bitkeeper revision 1.65.1.1 (3e54a501LFjblsT1VKSA9TGAMLch0A)
authorakw27@boulderdash.cl.cam.ac.uk <akw27@boulderdash.cl.cam.ac.uk>
Thu, 20 Feb 2003 09:50:57 +0000 (09:50 +0000)
committerakw27@boulderdash.cl.cam.ac.uk <akw27@boulderdash.cl.cam.ac.uk>
Thu, 20 Feb 2003 09:50:57 +0000 (09:50 +0000)
Added per-domain vif lists to /proc/xeno/domX/vif.

xen-2.4.16/common/network.c
xen-2.4.16/include/hypervisor-ifs/network.h
xenolinux-2.4.16-sparse/arch/xeno/drivers/dom0/dom0_core.c

index 608ca57037d0eabd2617b06414b9336c50cb48a4..fea01b326e81ba5b8761ba84c250b9fed8696480 100644 (file)
@@ -18,6 +18,8 @@
 #include <linux/skbuff.h>
 #include <xeno/netdevice.h>
 #include <xeno/in.h>
+#include <asm/domain_page.h>
+#include <asm/io.h>
 
 /* vif globals 
  * sys_vif_list is a lookup table for vifs, used in packet forwarding.
@@ -128,6 +130,33 @@ void destroy_net_vif(struct task_struct *p)
     kmem_cache_free(net_vif_cache, p->net_vif_list[i]);
 }
 
+/* vif_query - Call from the proc file system to get a list of vifs 
+ * assigned to a particular domain.
+ */
+
+void vif_query(vif_query_t *vq)
+{
+    struct task_struct *dom_task;
+    char buf[128];
+    int i;
+
+    if ( !(dom_task = find_domain_by_id(vq->domain)) )
+    {
+        return;
+    }
+
+    *buf = '\0';
+
+    for (i=0; i < dom_task->num_net_vifs; i++)
+    {
+        sprintf(buf + strlen(buf), "%d\n", dom_task->net_vif_list[i]->id);
+    }
+
+    copy_to_user(vq->buf, buf, strlen(buf) + 1);
+    
+}
+        
+
 /* print_vif_list - Print the contents of the global vif table.
  */
 
@@ -426,6 +455,11 @@ long do_network_op(network_op_t *u_network_op)
         print_net_rule_list();
     }
     break;
+
+    case NETWORK_OP_VIFQUERY:
+    {
+        vif_query(&op.u.vif_query);
+    }
     
     default:
         ret = -ENOSYS;
index f3f13dc77b8fb219fe97deeff93b9c137be0fdfd..d47b0a2e7c08377bec0114267426d88fc6bbced0 100644 (file)
@@ -85,6 +85,12 @@ typedef struct net_rule_st
     u16  action;
 } net_rule_t;
 
+typedef struct vif_query_st
+{
+    unsigned int    domain;
+    char            *buf;   // where to put the reply -- guest virtual address
+} vif_query_t;
+
 /* Network trap operations and associated structure. 
  * This presently just handles rule insertion and deletion, but will
  * evenually have code to add and remove interfaces.
@@ -93,6 +99,7 @@ typedef struct net_rule_st
 #define NETWORK_OP_ADDRULE      0
 #define NETWORK_OP_DELETERULE   1
 #define NETWORK_OP_GETRULELIST  2
+#define NETWORK_OP_VIFQUERY     3
 
 typedef struct network_op_st 
 {
@@ -100,6 +107,7 @@ typedef struct network_op_st
     union
     {
         net_rule_t net_rule;
+        vif_query_t vif_query;
     }
     u;
 } network_op_t;
index 86ac7ebab54fbc06d64df3a2b885cfd22ed6694c..f8af85358b5b5f84d09a22f3e4010e66131cf721 100644 (file)
@@ -49,6 +49,7 @@ typedef struct proc_mem_data {
 #define MAX_LEN         16
 #define DOM_DIR         "dom"
 #define DOM_MEM         "mem"
+#define DOM_VIF         "vif"
 
 #define MAP_DISCONT     1
 
@@ -72,11 +73,50 @@ static int cmd_read_proc(char *page, char **start, off_t off,
     return strlen(page);
 }
 
+static ssize_t dom_vif_read(struct file * file, char * buff, size_t size, loff_t * off)
+{
+    char hyp_buf[128]; // Hypervisor is going to write its reply here.
+    network_op_t op;
+    static int finished = 0;
+
+    // This seems to be the only way to make the OS stop making read requests
+    // to the file.  When we use the fileoperations version of read, offset 
+    // seems to be ignored altogether.
+    
+    if (finished) 
+    {
+        finished = 0;
+        return 0;
+    }
+    
+    op.cmd = NETWORK_OP_VIFQUERY;
+    op.u.vif_query.domain = (unsigned int) ((struct proc_dir_entry *)file->f_dentry->d_inode->u.generic_ip)->data;
+    op.u.vif_query.buf = hyp_buf;
+
+    strcpy(hyp_buf, "Error getting domain's vif list from hypervisor.\n"); // This will be replaced if everything works.
+
+    (void)HYPERVISOR_network_op(&op);
+
+    if (*off >= (strlen(hyp_buf)+1)) return 0;
+    
+    copy_to_user(buff, hyp_buf, strlen(hyp_buf));
+    
+    finished = 1;
+    
+    return strlen(hyp_buf)+1;
+}
+
+struct file_operations dom_vif_ops = {
+    read:    dom_vif_read
+};
+
+
 static void create_proc_dom_entries(int dom)
 {
     struct proc_dir_entry * dir;
     dom_procdata_t * dom_data;
     char dir_name[MAX_LEN];
+    struct proc_dir_entry * file;
 
     snprintf(dir_name, MAX_LEN, "%s%d", DOM_DIR, dom);
 
@@ -85,6 +125,15 @@ static void create_proc_dom_entries(int dom)
 
     dir = proc_mkdir(dir_name, xeno_base);
     dir->data = dom_data;
+    
+    file = create_proc_entry(DOM_VIF, 0600, dir);
+    if (file != NULL)
+    {
+        file->owner         = THIS_MODULE;
+        file->nlink         = 1;
+        file->proc_fops     = &dom_vif_ops;
+        file->data          = (void *) dom;
+    }
 }
 
 static ssize_t dom_mem_write(struct file * file, const char * buff, 
@@ -159,6 +208,7 @@ static int dom_map_mem(unsigned int dom, unsigned long pfn, int tot_pages)
                 ret = 0;
                 break;
             }
+
             ret = -EAGAIN;
             break;
         }